.js
window.loadedScripts = {};
.js
function loadScript(sources) {
if (sources in window.loadedScripts) return;
window.loadedScripts[sources] = true;
var script = document.createElement('script');
script.src = sources;
script.async = false;
document.body.appendChild(script);
const promise = new Deferred();
script.addEventListener('load', () => {
promise.resolve();
});
return promise.promise;
}
core.ForceGraph3D = async (args, env) => {
const data = await interpretate(args[0], env);
await loadScript('https://unpkg.com/3d-force-graph');
await interpretate.shared.SpriteText.load();
const SpriteText = interpretate.shared.SpriteText.SpriteText;
const opts = await core._getRules(args, env);
// Build labels mapping
const labels = (opts.VertexLabels || []).reduce((acc, { lhs, rhs }) => {
acc[lhs] = rhs;
return acc;
}, {});
// Collect node IDs and construct links
const nodeIds = new Set();
const links = data.map(({ lhs, rhs }) => {
nodeIds.add(lhs);
nodeIds.add(rhs);
return { source: String(rhs), target: String(lhs) };
});
// Create nodes with labels
const nodes = Array.from(nodeIds).map(id => ({
id: String(id),
label: labels[id] || String(id),
}));
// Initialize the 3D force graph
const Graph = ForceGraph3D()(env.element)
.graphData({ nodes, links })
.nodeThreeObject(node => {
const sprite = new SpriteText(node.label);
sprite.material.depthWrite = true; // Make sprite background transparent
sprite.color = 'white';
sprite.textHeight = 8;
return sprite;
})
.nodeThreeObjectExtend(false);
// Apply optional charge strength
if ('Charge' in opts) {
Graph.d3Force('charge').strength(opts.Charge);
}
env.local.Graph = Graph;
};
core.ForceGraph3D.destroy = () => {
}
core.ForceGraph3D.virtual = true
CreateFrontEndObject[ForceGraph3D[tagsGraph]]